/* Пример программы для доступа к I2C EEPROM 24C01 от Atmel на 128 байт */

/* Микроконтроллер  AT90S2313, шина I2C подключена к PORTB.
   Для сигнала sda используем 0 бит порта, 
   для scl - 1 бит порта (рис. 357) */

#include <90s2313.h> 	// подключаем  заголовочный файл используемого 
					// микроконтроллера AVR

/* Перед подключением файла i2c.h, объявим порт, используемый 
   для подключения шины I2C */

/* Шина I2C подключена к PORTB микроконтроллера AT90S2313 
   Адрес порта находим в файле 90s2313.h в строке: sfrb PORTB=0x18;
   Для сигнала sda используем 0 бит порта, для scl - 1 бит порта */
#asm 
.equ __i2c_port=0x18 
.equ __sda_bit=0 
.equ __scl_bit=1 
#endasm 

/* теперь можно подключить Функции I2C */ 
#include <i2c.h>

/* Для осуществления задержки в 10 мс понадобится функция  delay_ms. 
   Для этого подключим заголовочный файл delay.h */ 
#include <delay.h>

#define addres_eep 0xa0	// В соответствии с описанием на 24C01 определим 
					// адрес для EEPROM: 0b10100000=0xa0. Это адрес
					// для записи. Адрес для чтения: 0b10100001=0xa1

typedef unsigned char byte; 	// Для удобства определим тип данных byte, 
						// byte = unsigned char

/* прочитаем байт из EEPROM */
/* Определим функцию read_eep, которая читает байт из EEPROM 
   по адресу address_byte и возвращает его значение*/

byte read_eep(byte address_byte) 
{
		byte data; 			// Определяем переменную data, в которой будет
 					// храниться считанное значение
		i2c_start();		// Генерируем стартовое условие
		i2c_write(addres_eep); 	// Передаем в шину I2C адрес EEPROM с младшим
						// байтом = 0, т.к. следующая операция - запись
		i2c_write(address_byte); 	// Передаем в шину I2C адрес байта,
							// который требуется прочитать
		i2c_start();			// Генерируем стартовое условие
		i2c_write(addres_eep | 1); 	// Изменяем самый младший байт адреса 
							// EEPROM на 1, т.к. будем производить
 						// операцию чтения
		data=i2c_read(0); 	// Читаем байт из шины I2C в переменную data
		i2c_stop();			// Генерируем стоповое условие
		return data; 		// Возвращаем значение переменной data
} 

/* запишем байт в EEPROM */ 
/* Определим функцию write_eep, которая записывает байт data в EEPROM 
   по адресу address_byte.
   Т.к. функция ничего не возвращает, объявим ее как void */

void write_eep(byte address_byte, byte data) 
{ 
		i2c_start();		// Генерируем стартовое условие
		i2c_write(addres_eep); 		// Передаем в шину I2C адрес EEPROM
		i2c_write(address_byte); 	// Передаем в шину I2C адрес ячейки,
							// куда требуется записать байт
		i2c_write(data); 		// Записываем байт данных data
		i2c_stop();			// Генерируем стоповое условие
		delay_ms(10); 		// завершаем операцию записи задержкой 10 мс 
} 

/* Основная функция программы */ 
void main(void) 
{ 
		byte x; 		// Определяем переменную x
		i2c_init();		// Инициализируем шину I2C
		
		write_eep(0x12,0x34); 	// С помощью функции write_eep записываем байт 
  					// 34h по адресу 12h
		 
		x=read_eep(0x34); 	// С помощью функции read_eep читаем байт
  					// по адресу 12h в переменную x
						// В результате x=34h
		while (1); 		// завершаем основную функцию бесконечным циклом 
}
